/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package main;

import data.AlgorithmInput;
import data.ClusteringGraphData;
import data.ClusteringInput;
import data.CompressionGraphData;
import data.ConfigurationGraphData;
import data.ConfigurationInput;
import data.Data;
import data.MirroringGDWithoutBS;
import data.Saver;
import data.GeneralDefinitions.ClusteringPriorityParameters;
import data.GeneralDefinitions.DiskType;
import data.GeneralDefinitions.OrderingParameters;
import data.GraphData;
import data.MirroringInput;

import java.io.File;
import java.io.IOException;
import java.util.Calendar;
import java.util.Vector;

import sql.SQLiteDB;
import logic.ClusteringAlgorithm;
import logic.CompressionAlgorithm;
import logic.ConfigurationAlgorithm;
import logic.MirroringAlgorithm;
import memorydata.MemoryDataMaps;

/**
 *
 * @author Elad
 */
public class Engine {

	private ToGuiFacade _toGuiFacade;
	private Data _data;
	private MirroringAlgorithm _mirrorAlgo;
	private CompressionAlgorithm _compressionAlgo;
	private ClusteringAlgorithm _clusteringAlgo;
	private ConfigurationAlgorithm _configurationAlgo;

	private GraphData _gData;
	private AlgorithmInput _algoInput;

	private Saver saver;

	public Engine(Data data, ToGuiFacade toGuiFacade) {
		this._toGuiFacade = toGuiFacade;
		this._data = data;
	}

	public void set_data(Data _data) {
		this._data = _data;
	}
	public boolean isDataSet() {
		return _data != null;
	}

	void computeClustering(int numOfClusters, Calendar startDate, Calendar endDate, ClusteringPriorityParameters priorityParam) {
		_clusteringAlgo = new ClusteringAlgorithm();
		_algoInput = new ClusteringInput(numOfClusters, startDate, endDate, priorityParam);
		_gData = _clusteringAlgo.compute(_algoInput, _data);
		
		_toGuiFacade.showClusteringGraph(_gData);
	}

	void computeCompression() {
		_compressionAlgo = new CompressionAlgorithm();
		_algoInput = null;
		_gData = _compressionAlgo.compute(null, _data);
		_toGuiFacade.showCompressionGraph(_gData);
	}

	void computeConfiguration(double price, double performance, double powerConsump, Calendar startDate, Calendar endDate, OrderingParameters priorityParam) {
		_algoInput = new ConfigurationInput(price, performance, powerConsump, startDate, endDate, priorityParam);
		_configurationAlgo = new ConfigurationAlgorithm();
		//		System.out.println(" @@@@@@@@ data = "+_data);
		_gData = _configurationAlgo.compute(_algoInput, _data);
		_toGuiFacade.showConfigurationGraph(_gData);

		//		Saver s = new Saver("test");
		//		s.save(algoInput, ((ConfigurationGraphData)gData));

	}

	void computeMirroring(DiskType typeOfDisk, Double bufferSize) {
		_algoInput = new MirroringInput(typeOfDisk, bufferSize);
		_mirrorAlgo = new MirroringAlgorithm();
		_gData = _mirrorAlgo.compute(_algoInput, _data);
		//        System.out.println("gdata "+gData);
		_toGuiFacade.showMirroringGraph(_gData);
	}

	void parse(File file){
		//TODO  remove the check if the file is db or csv - already been done in GUI - InputFile
		String filename = file.getName();
		String name = filename.substring(0, filename.lastIndexOf("."));
		String suffix = filename.substring(filename.lastIndexOf(".")+1);
		if (suffix.equals("csv")){
			if (true){
				_data = new MemoryDataMaps();
				//				_data = new MemoryData();
				_data.parse(file.getAbsolutePath());
			} else {
				File dbFile = new File(name+".db");
				if (dbFile.exists()){
					//_data = new SQLiteDB(name + ".db");
					//TODO display message/query what to do
					System.out.println("Database file already exists... what to do ?");
					_data = new SQLiteDB(name + ".db"); 
				} else {
					try {
						dbFile.createNewFile();
						SQLiteDB tmpData = new SQLiteDB(name + ".db");
						tmpData.createTables();
						_data = tmpData; 
						_data.parse(filename);
						System.out.println( "Done parsing file - " + filename);
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
			//TODO display success message or any output to the user/progress bar/etc
		} else {
			System.out.println("Error - wrong file suffix");
			//TODO display error message	
		}
	}

	public void loadPreviousGraph(File selectedFile) {
		String name = selectedFile.getAbsolutePath();
		name = name.substring(0, name.lastIndexOf("."));
		saver = new Saver(name);
		Vector<String> data = saver.getFileContent();
		if (!data.isEmpty()){
			_toGuiFacade.askForInput(data);
		} else {
			System.out.println("Engine, loadPreviousGraph - no graphs found");
		}
	}

	public void showPreviousGraph(String section){
		System.out.println(section);
		section = section.split("\\|")[0];
		System.out.println("Engine, showPerviousGraph - " + section);
		GraphData gData = saver.loadResults(section);
		//TODO make this not ugly
		if (gData instanceof ClusteringGraphData){
			_toGuiFacade.showClusteringGraph(gData);
		} else if (gData instanceof MirroringGDWithoutBS){
			_toGuiFacade.showMirroringGraph(gData);
		} else if (gData instanceof CompressionGraphData){
			_toGuiFacade.showCompressionGraph(gData);
		} else if (gData instanceof ConfigurationGraphData){
			_toGuiFacade.showConfigurationGraph(gData);
		}
	}

	public void save() {
		if (_data!=null){
			String filename = _data.getFIleName();
			if (filename == null) filename = "default.csv";
			filename = filename.substring(0, filename.lastIndexOf('.'));
			Saver s = new Saver(filename);
			s.save(_algoInput, _gData);
		}
	}
}
